package com.anywhere.freightman.app.controller;


import com.anywhere.freightman.app.controller.request.*;
import com.anywhere.freightman.app.controller.response.DriverExInfoResponse;
import com.anywhere.freightman.car.controller.request.DriverRequest;
import com.anywhere.freightman.car.model.CarModel;
import com.anywhere.freightman.car.model.DriverModel;
import com.anywhere.freightman.car.service.IDriverService;
import com.anywhere.freightman.common.ContextKeys;
import com.anywhere.freightman.common.annotation.Permission;
import com.anywhere.freightman.common.entity.ReturnResp;
import com.anywhere.freightman.common.entity.car.DriverEntity;
import com.anywhere.freightman.common.enumeration.*;
import com.anywhere.freightman.common.ex.CustomException;
import com.anywhere.freightman.common.utils.BPwdEncoderUtils;
import com.anywhere.freightman.order.controller.resp.WaybillDetailsResp;
import com.anywhere.freightman.order.controller.resp.WaybillResp;
import com.anywhere.freightman.order.model.AddressBookModel;
import com.anywhere.freightman.order.model.WaybillModel;
import com.anywhere.freightman.order.service.IAddressBookService;
import com.anywhere.freightman.order.service.IGoodsService;
import com.anywhere.freightman.order.service.IWaybillLogService;
import com.anywhere.freightman.order.service.IWaybillService;
import com.anywhere.freightman.system.service.IAccessTokenService;
import com.google.common.base.Strings;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("app/driver")
@Api(tags = "司机端接口")
public class DriverAppController {
    @Autowired
    private IDriverService driverService;
    @Autowired
    private IWaybillService waybillService;
    @Autowired
    private IAddressBookService addressBookService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IWaybillLogService waybillLogService;
    @Autowired
    private IAccessTokenService accessTokenService;


    @PostMapping("reg")
    @ApiOperation("登录")
    public ReturnResp reg(@RequestBody DriverRegRequest request) {
        if (Strings.isNullOrEmpty(request.getTel())){
            throw new CustomException("请输入手机号");
        }

        if (Strings.isNullOrEmpty(request.getRealName())){
            throw new CustomException("请输入真实姓名");
        }

        if (Strings.isNullOrEmpty(request.getPassword())){
            throw new CustomException("请输入登录密码");
        }

        if (Strings.isNullOrEmpty(request.getIdentityNo())){
            throw new CustomException("请输入身份证号");
        }

        if (Strings.isNullOrEmpty(request.getPracticing())){
            throw new CustomException("请输入从业资格证号");
        }

        if (Strings.isNullOrEmpty(request.getTransportLicense())){
            throw new CustomException("请输入运输经营许可号");
        }

        if (Strings.isNullOrEmpty(request.getAddress())){
            throw new CustomException("请输入联系地址");
        }
        DriverModel model = new DriverModel();
        BeanUtils.copyProperties(request, model);
        model.setStatus(DriverStatus.REST);
        model.setInsertTime(new Date());
        model.setType(DriverType.OWN);
        model.setCompanyId(-1L);
        model.setPassword(BPwdEncoderUtils.BCryptPassword(request.getPassword()));
        driverService.insert(model);
        return ReturnResp.buildOk();
    }

    @PostMapping("login")
    @ApiOperation("登录")
    public ReturnResp login(@RequestParam("tel") String tel,
                            @RequestParam("password") String password) {
        DriverEntity entity = driverService.login(tel, password);
        return ReturnResp.buildOk(entity);
    }

    @PostMapping("logout")
    @ApiOperation("注销")
    @Permission(code = "APP_DRIVER")
    public ReturnResp logout(HttpServletRequest httpRequest) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        accessTokenService.logout(account.getId(), TokenType.DRIVER);
        return ReturnResp.buildOk();
    }

    @PostMapping("pwd")
    @ApiOperation("修改密码")
    @Permission(code = "APP_DRIVER")
    public ReturnResp updatePwd(HttpServletRequest httpRequest,
                                @RequestBody UpdatePwdRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        driverService.updatePwd(account.getId(), request.getPassword(), request.getNewPassword());
        return ReturnResp.buildOk();
    }

    @GetMapping("info")
    @ApiOperation("获取司机账号信息")
    @Permission(code = "APP_DRIVER")
    public ReturnResp getInfo(HttpServletRequest httpRequest) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        return ReturnResp.buildOk(account);
    }

    @GetMapping("car")
    @ApiOperation("获取司机绑定的车辆")
    @Permission(code = "APP_DRIVER")
    public ReturnResp getCarList(HttpServletRequest httpRequest) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        List<CarModel> carList = driverService.getCarList(account.getId());
        return ReturnResp.buildOk(carList);
    }

    @GetMapping("exInfo")
    @ApiOperation("获取司机其他信息")
    @Permission(code = "APP_DRIVER")
    public ReturnResp getExInfo(HttpServletRequest httpRequest) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        DriverExInfoResponse resp = new DriverExInfoResponse();
        DriverModel model = driverService.getById(account.getId());
        BeanUtils.copyProperties(model, resp);
        List<CarModel> carList = driverService.getCarList(account.getId());
        resp.setCarList(carList);
        resp.setCarCount(carList.size());
        return ReturnResp.buildOk(resp);
    }

    @GetMapping("order")
    @ApiOperation("查询可接运单")
    @Permission(code = "APP_DRIVER")
    public ReturnResp getOrderList(HttpServletRequest httpRequest,
                                   @RequestParam(value = "orderNo", required = false) String orderNo,
                                   @RequestParam(value = "type", required = false) WaybillType type) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        List<WaybillModel> modelList = waybillService.getOwnerList(account.getId(), orderNo, type);

        List<WaybillResp> list = new ArrayList<>();
        modelList.forEach(item -> {
            WaybillResp response = new WaybillResp();
            BeanUtils.copyProperties(item, response);
            AddressBookModel shipper = addressBookService.getById(item.getShipperId());
            response.setShipper(shipper);
            AddressBookModel receiver = addressBookService.getById(item.getReceiverId());
            response.setReceiver(receiver);
            list.add(response);
        });
        return ReturnResp.buildOk(list);
    }

    @GetMapping("order/{orderNo}")
    @ApiOperation("运单信息")
    @Permission(code = "APP_DRIVER")
    public ReturnResp getDetails(HttpServletRequest httpRequest,
                                 @PathVariable("orderNo") String orderNo) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);

        WaybillModel model = waybillService.getByNo(orderNo);
        if (model == null) {
            throw new CustomException("运单信息不存在");
        }

        boolean checkDriver = waybillService.checkDriver(orderNo, account.getId());
        if (!model.getType().equals(WaybillType.PUBLIC) && !checkDriver) {
            throw new CustomException("运单信息不存在");
        }

        WaybillDetailsResp response = new WaybillDetailsResp();
        BeanUtils.copyProperties(model, response);
        AddressBookModel shipper = addressBookService.getById(response.getShipperId());
        response.setShipper(shipper);
        AddressBookModel receiver = addressBookService.getById(response.getReceiverId());
        response.setReceiver(receiver);
        response.setGoodsList(goodsService.getListByOrderNo(orderNo));
        response.setCarAndDriverList(waybillService.getListCarAndDriver(orderNo));
        response.setLogs(waybillLogService.getListByOrderNo(orderNo));

        response.setFileList(waybillService.getFileList(orderNo));

        return ReturnResp.buildOk(response);
    }

    @PutMapping("order")
    @ApiOperation("司机接单")
    @Permission(code = "APP_DRIVER")
    public ReturnResp accessOrder(HttpServletRequest httpRequest,
                                  @RequestBody AccessOrderRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        WaybillModel waybill = waybillService.getByNo(request.getOrderNo());
        if (waybill == null) {
            throw new CustomException("订单信息不存在");
        }
        if (!waybill.getStatus().equals(WaybillStatus.WAIT_PICK)) {
            throw new CustomException("不能接受该订单");
        }

        if (waybill.getType().equals(WaybillType.DIRECT)) {
            if (!waybillService.checkDriver(request.getOrderNo(), account.getId())) {
                throw new CustomException("对不起，你不是本运单的计划司机");
            }
        }
        waybillService.accessOrder(request.getOrderNo(), account.getId(), request.getCarId(), request.getPrice());
        return ReturnResp.buildOk();
    }

    @PutMapping("order/start")
    @ApiOperation("开始运输")
    @Permission(code = "APP_DRIVER")
    public ReturnResp orderStart(HttpServletRequest httpRequest,
                                 @RequestBody OrderNoRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        WaybillModel waybill = waybillService.getByNo(request.getOrderNo());
        if (waybill == null) {
            throw new CustomException("订单信息不存在!");
        }
        if (!waybill.getStatus().equals(WaybillStatus.PICKED)) {
            throw new CustomException("不能接受该订单");
        }
        waybillService.orderStart(request.getOrderNo(), account.getId());
        return ReturnResp.buildOk();
    }

    @PostMapping("order/upload")
    @Permission(code = "APP_DRIVER")
    public ReturnResp uploadFile(HttpServletRequest httpRequest,
                                 @RequestBody UploadRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        waybillService.insertFile(request.getOrderNo(), request.getFileId(), account.getId());
        return ReturnResp.buildOk();
    }

    @PutMapping("order/arrivals")
    @ApiOperation("到达目的地")
    @Permission(code = "APP_DRIVER")
    public ReturnResp orderArrivals(HttpServletRequest httpRequest,
                                    @RequestBody OrderNoRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        waybillService.orderArrivals(request.getOrderNo(), account.getId());
        return ReturnResp.buildOk();
    }

    @PutMapping("order/done")
    @ApiOperation("确认货物到达")
    @Permission(code = "APP_DRIVER")
    public ReturnResp orderDone(HttpServletRequest httpRequest,
                                @RequestBody DoneRequest request) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        waybillService.driverConfirmCode(request.getOrderNo(), account.getId(), request.getCode());
        return ReturnResp.buildOk();
    }

    @DeleteMapping("image/{id}")
    @ApiOperation("删除文件")
    @Permission(code = "APP_DRIVER")
    public ReturnResp deleteImage(HttpServletRequest httpRequest,
                                  @PathVariable("id") long fileId) {
        DriverEntity account = (DriverEntity) httpRequest.getAttribute(ContextKeys.REQUEST_ACCOUNT);
        waybillService.removeFile(fileId);
        return ReturnResp.buildOk();
    }

}
